﻿#include "FMeshWithOutline.h"

#include "MaterialSrc/OutlineMaterial.h"

void FMeshWithOutline::OnInit()
{
	FMesh::OnInit();

	OutLineMaterial = std::make_shared<FOutlineMaterial>();
	OutLineMaterial->Init();
}

void FMeshWithOutline::Draw(const FDrawArg& DrawArg) const
{
	const auto MutableThis = const_cast<FMeshWithOutline*>(this);

	// Step 1
	// 首先绘制正常的物体，并且将物体 记录在 模板缓存中  设置为 1
	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
	glStencilFunc(GL_ALWAYS, 1, 0xff);
	glStencilMask(0xFF);

	FMesh::Draw(DrawArg);

	// Step 2
	// 放大一点物体，将物体的材质改为纯色
	// 绘制物体，模板缓存中 不为1 的片段会被保留 ，也就是描边部分被保留
	glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
	glStencilMask(0);
	glDisable(GL_DEPTH_TEST);

	const auto TempMaterial = Material;
	MutableThis->Material = OutLineMaterial;

	constexpr float Scale = 1.05f;

	const auto TempTransform = Transform;
	MutableThis->SetTransform(glm::scale(Transform, glm::vec3(Scale)));
	FMesh::Draw(DrawArg);

	MutableThis->SetTransform(TempTransform);

	MutableThis->Material = TempMaterial;

	// Step 3
	// 恢复之前的设置

	// 这里重新必须开启 模板可写入的掩码
	// glStencilMask 会影响 glClear 导致模板无法被清零
	// https://stackoverflow.com/questions/33548848/issue-when-updating-stencil-buffer-in-opengl
	glStencilMask(0xFF);

	glEnable(GL_DEPTH_TEST);
}
